unit MRBuscaPanel;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls, DB, Vcl.Buttons,
  Vcl.Mask, Vcl.StdCtrls, ZDataSet ;

type
  TMrBuscaPanel = class(TPanel)
  private
    FDataSource: TDataSource;
    vCamposWhere: TStrings;
    btBusca : TBitBtn;
    btLimpar : TBitBtn;
    fLinhaWhere: integer;
    fprimeiraTag: String;
    procedure SetCamposWhere(const Value: TStrings);
    procedure SetDataSource(const Value: TDataSource);
    procedure ButtonClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure CriaEdits;
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
  published
    property CamposWhere: TStrings read vCamposWhere write SetCamposWhere;
    property DataSource: TDataSource read FDataSource write SetDataSource;
    property LinhaWhere: Integer read fLinhaWhere write fLinhaWhere;
    property PrimeiraTag: String read fprimeiraTag write fprimeiraTag;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MRSoftware', [TMrBuscaPanel]);
end;

{ TMrBuscaPanel }

procedure TMrBuscaPanel.Button2Click(Sender: TObject);
var
    i, j, vTop, vLeft, vLinha, vLinhaAnt, vTamanho: integer;
    lblTemp: TLabel;
    vEdit : TObject;
    vCampo, vField, vTag, vWhere: String;
begin
    for i := 0 to vCamposWhere.Count - 1 do
    begin
        vCampo := vCamposWhere[i];

        j := pos(',',vCampo);
        vLinha := StrToInt(Copy(vCampo,1,j-1));
        vCampo := Copy(vCampo,j+1,200);

        j := pos(',',vCampo);
        vField := Copy(vCampo,1,j-1);
        vCampo := Copy(vCampo,j+1,200);

        vEdit := (Self.FindComponent('MrEdit_'+vField));

        if vEdit is TMaskEdit then
        begin
            if length((vEdit as TMaskEdit).Text) > 0 then
            begin
                (vEdit as TMaskEdit).Text := '';
            end;
        end else if vEdit is TComboBox then
        begin
            (vEdit as TComboBox).ItemIndex := 0;
        end;
    end;


end;

procedure TMrBuscaPanel.ButtonClick(Sender: TObject);
var
    i, j, vTop, vLeft, vLinha, vLinhaAnt, vTamanho: integer;
    lblTemp: TLabel;
    vEdit : TObject;
    vCampo, vField, vTag, vWhere, TipoCampo, vTemp: String;
begin
    FDataSource.DataSet.Close;

    vTag := fprimeiratag;
    vWhere := '';
    for i := 0 to vCamposWhere.Count - 1 do
    begin
        vCampo := vCamposWhere[i];

        j := pos(',',vCampo);
        vLinha := StrToInt(Copy(vCampo,1,j-1));
        vCampo := Copy(vCampo,j+1,200);

        vtop :=  + ((vLinha - 1) * 36) + 2;
        if vTop <> vLinhaAnt then
        begin
            vLinhaAnt := vTop;
            vLeft := 2;
        end;

        j := pos(',',vCampo);
        vField := Copy(vCampo,1,j-1);
        vCampo := Copy(vCampo,j+1,200);

        j := pos(',',vCampo);
        vTamanho := StrToInt(Copy(vCampo,1,j-1));
        vCampo := Copy(vCampo,j+1,200);

        lblTemp := (Self.FindComponent('MrLabel_'+vField) as TLabel);
        vEdit := (Self.FindComponent('MrEdit_'+vField) as TObject);

        tipocampo := 'string';
        if (FDataSource.DataSet.FieldByName(vField).DataType = ftDate) or
           (FDataSource.DataSet.FieldByName(vField).DataType = ftDateTime)
        then
            tipocampo := 'data'
        else if (FDataSource.DataSet.FieldByName(vField).DataType = ftCurrency)
           or (FDataSource.DataSet.FieldByName(vField).DataType = ftFloat)
           or (FDataSource.DataSet.FieldByName(vField).DataType = ftBCD)
        then
            tipocampo := 'decimal';




        if vEdit is TMaskEdit then
        begin
            if length((vEdit as TMaskEdit).Text) > 0 then
            begin
                if tipocampo = 'data' then
                begin
                    try
                        (vEdit as TMaskEdit).Text := FormatDateTime('dd/mm/yyyy',
                            StrToDate((vEdit as TMaskEdit).Text));
                    except end;
                    vWhere := vWhere + vTag + ' ' + vField + ' = '''+
                        FormatDateTime('yyyy-mm-dd',
                            StrToDate((vEdit as TMaskEdit).Text)) + ''' ';
                end else if tipocampo = 'decimal' then
                begin
                    vTemp := (vEdit as TMaskEdit).Text;
                    vTemp := StringReplace(vTemp,'.','',[rfReplaceAll]);
                    vTemp := StringReplace(vTemp,',','.',[rfReplaceAll]);
                    try
                        (vEdit as TMaskEdit).Text := FormatFloat('#,##0.00',
                            StrToCurr(vTemp));
                    except end;
                    vWhere := vWhere + vTag + ' ' + vField + ' = '+
                        vTemp ;
                end else if tipocampo = 'string' then
                begin
                    vWhere := vWhere + vTag + ' ' + vField + ' like '''+
                        (vEdit as TMaskEdit).Text + '%'' ';

                end;
                vTag := ' and ';
            end;
        end else if vEdit is TComboBox then
        begin
             if length((vEdit as TComboBox).Text) > 0 then
             begin
                 vWhere := vWhere + vTag + ' ' + vField + ' = '''+
                    (vEdit as TComboBox).Text + ''' ';
                  vTag := ' and ';
             end;
        end;

    end;

    if (FDataSource.DataSet is TZQuery) then
        (FDataSource.DataSet as TZQuery).SQL[fLinhaWhere] := vWhere
    else if (FDataSource.DataSet is TZReadOnlyQuery) then
        (FDataSource.DataSet as TZReadOnlyQuery).SQL[fLinhaWhere] := vWhere;

    FDataSource.DataSet.Open;

end;

constructor TMrBuscaPanel.Create(AOwner: TComponent);
begin
  inherited;
    vCamposWhere := TStringList.Create;
    vCamposWhere.Text := '1,campo,10,[opt1,opt2,opt3],';

    btBusca := TBitBtn.Create(Self);
    btBusca.Parent := Self;
    btbusca.Top := Height - 30;
    btBusca.Left := Width - 100;
    btBusca.Anchors := [akBottom, akRight];
    btBusca.Caption := 'Buscar';
    btBusca.Enabled := true;
    btBusca.OnClick := ButtonClick;

    btLimpar := TBitBtn.Create(Self);
    btLimpar.Parent := Self;
    btLimpar.Top := Height - 30;
    btLimpar.Left := Width - 200;
    btLimpar.Anchors := [akBottom, akRight];
    btLimpar.Caption := 'Limpar';
    btLimpar.Enabled := true;
    btLimpar.OnClick := Button2Click;
    //CriaEdits;
end;

procedure TMrBuscaPanel.CriaEdits;
var
    i, j, vTop, vLeft, vLinha, vLinhaAnt, vTamanho: integer;
    lblTemp: TLabel;
    vEdit : TMaskEdit;
    vCombo: TComboBox;
    vCampo, vField, vTemp: String;
    opcoes: TStrings;
begin
    for i := 0 to self.ComponentCount -1 do
    begin
      try
          while (Components[i] is TLabel) do
              Components[i].Free;
      except
      end;
    end;

    for i := 0 to self.ComponentCount -1 do
    begin
      try
          while (Components[i] is TMaskEdit) do
              Components[i].Free;
      except
      end;
    end;

    for i := 0 to self.ComponentCount -1 do
    begin
      try
          while (Components[i] is TComboBox) do
              Components[i].Free;
      except
      end;
    end;

    if (vCamposWhere.Count <= 0) then
        Exit;

    vtop := 2;
    vLeft := 2;
    vLinhaAnt := 1;
    opcoes := TStringList.Create;
    opcoes.Text := '';
    for i := 0 to vCamposWhere.Count - 1 do
    begin
        vCampo := vCamposWhere[i];

        j := pos(',',vCampo);
        vLinha := StrToInt(Copy(vCampo,1,j-1));
        vCampo := Copy(vCampo,j+1,200);

        vtop :=  + ((vLinha - 1) * 36) + 2;
        if vTop <> vLinhaAnt then
        begin
            vLinhaAnt := vTop;
            vLeft := 2;
        end;

        j := pos(',',vCampo);
        vField := Copy(vCampo,1,j-1);
        vCampo := Copy(vCampo,j+1,200);

        j := pos(',',vCampo);
        vTamanho := StrToInt(Copy(vCampo,1,j-1));
        vCampo := Copy(vCampo,j+1,200);

        opcoes.Text := '';
        if copy(vCampo,1,1) = '[' then
        begin
            vCampo := Copy(vCampo,2,200);
            while Copy(vCampo,1,1) <> ']' do
            begin
                j := pos(',',vCampo);
                vTemp := Copy(vCampo,1,j-1);
                vCampo := Copy(vCampo,j+1,200);
                opcoes.Add(vTemp);
            end;
            vCampo := Copy(vCampo,2,200);
        end;

        lblTemp := TLabel.Create(Self);
        lblTemp.Parent := Self;
        lbltemp.Top := vTop;
        lblTemp.Left := vLeft;
        lbltemp.Caption := FDataSource.DataSet.FieldByName(vField).DisplayLabel;;
        lblTemp.Width := vTamanho;
        lblTemp.Name := 'MrLabel_'+vField;

        if opcoes.Text <> '' then
        begin
            vCombo := TComboBox.Create(Self);
            vCombo.Parent := Self;
            vCombo.Top := vTop + 13;
            vCombo.Left := vLeft;
            vCombo.Width := vTamanho;
            vCombo.Name := 'MrEdit_'+vField;
            vCombo.Style := csDropDownList;
            vCombo.Items.Assign(opcoes);

        end else
        begin
            vEdit := TMaskEdit.Create(Self);
            vEdit.Parent := Self;
            vEdit.Top := vTop + 13;
            vEdit.Left := vLeft;
            vEdit.Width := vTamanho;
            vEdit.Name := 'MrEdit_'+vField;
            vEdit.EditMask := FDataSource.DataSet.FieldByName(vField).EditMask;
            vEdit.text := '';
        end;

        vLeft := vLeft + vTamanho + 3;
    end;

end;

procedure TMrBuscaPanel.SetCamposWhere(const Value: TStrings);
begin
    vCamposWhere.Assign(Value);
    CriaEdits;

end;

procedure TMrBuscaPanel.SetDataSource(const Value: TDataSource);
begin
    FDataSource := Value;

end;

end.
